package ml.practicum.learn;

import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import ml.practicum.feature.LVFeature;
import ml.practicum.feature.Feature.FeatureRole;
import ml.practicum.logistic.BasicLV;
import ml.practicum.table.HeadedTable;
/**
 * Class to builds up a human readable representation for the model that is given
 * @author Joscha
 *
 */
public class PerceptronRepresentation implements Representation<BasicPerceptron<BasicLV>,HeadedTable<LVFeature<String>,String>> {
	
	public PerceptronRepresentation() {
		super();
		// TODO Auto-generated constructor stub
	}

	private HeadedTable<LVFeature<String>,String> processed;
	public HeadedTable<LVFeature<String>, String> getProcessed() {
		return processed;
	}

	public void setProcessed(HeadedTable<LVFeature<String>, String> processed) {

		this.processed = processed;
	}

	public BasicPerceptron<BasicLV> getPerceptron() {
		return perceptron;
	}

	public void setPerceptron(BasicPerceptron<BasicLV> perceptron) {
		this.perceptron = perceptron;
	}

	private BasicPerceptron<BasicLV> perceptron;
	
	public String toString(){
		ByteArrayOutputStream result = new ByteArrayOutputStream(); 
		PrintStream output = new PrintStream(result);
		
		output.printf("Perceptron Representation: \nBias: %.2f\nOutput:\n",perceptron.getBias());
		
		for(LVFeature<String> feat:processed.getHeader()){
			if (feat.getRole() == FeatureRole.OUTPUT){
				if (feat.getMapping() != null){
					for (int i =0; i < feat.getMapping().size(); i++){
						output.printf("  %s = %d\n", feat.getMapping().get(i),i);
					}
				}
			}
		}
		output.println();
		int lastIndex = 0;
		for(int i = 0; i < processed.getRow(0).size(); i++){
			LVFeature<String> feat = processed.getHeader().get(i);
			int size= feat.processValue(processed.getRow(0).get(i)).size();
			double interval = (feat.getMax()-feat.getMin())/size;
			output.printf("Label: %s (min = %d max = %d interval = %.2f)\nWeights:\n",feat.getLabel(),feat.getMin(),feat.getMax(),interval );
			
			for(int j=0;j <size; j++){
				double weight = perceptron.getWeights().get(lastIndex+j);
				if (feat.getMapping() != null){
					output.printf("  %.10s = ", feat.getMapping().get(j));
				}else{
					output.printf("  %.0f-%.0f = ",feat.getMin() + interval*j,feat.getMin() + interval*(j+1));
				}
				output.printf("%.2f\n",weight);
			}
			output.println();
			lastIndex = size -1;
		}
		return result.toString();
	}	
}

